package org.llc.common.starter.handle;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.llc.common.model.Result;
import org.llc.common.starter.util.Oauth2ExceptionMessageUtil;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import org.llc.common.starter.constants.Oauth2ExceptionEnum;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 用来解决匿名用户访问无权限资源时的异常
 *
 * @author llc
 * @date 2019/12/9 9:59
 * @since 1.0.0
 */
@Slf4j
@Component
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {

    /**
     * springmvc启动时自动装配json处理类
     */
    private final ObjectMapper objectMapper;

    public AuthExceptionEntryPoint(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) {
        Throwable cause = authException.getCause();
        response.setStatus(HttpStatus.OK.value());
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        try {
            boolean flag = cause instanceof InvalidTokenException;
            String code = flag
                    //坏的token或过期token
                    ? Oauth2ExceptionEnum.INVALID_TOKEN.getCode()
                    //用户未登录
                    : Oauth2ExceptionEnum.USER_NOT_LOGGED_IN.getCode();
            Result result = Result.failed(code, !flag ?  Oauth2ExceptionEnum.USER_NOT_LOGGED_IN.getMsg() : Oauth2ExceptionEnum.INVALID_TOKEN.getMsg()+ Oauth2ExceptionMessageUtil.getExceptionMessage(authException.getMessage()));
            response.getWriter().write(objectMapper.writeValueAsString(result));
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            log.error("AuthExceptionEntryPoint commence exception : " , e.getMessage());
        }
    }
}